size_t UnicodeLens(char *from)
{
	size_t sum;
	unsigned char c;
	int more;
	sum = 0;
	while(c = (*from++))
	{
		if(c < 0x80)
			more = 0;
		else if(c < 0xe0)
			more = 1;
		else
			more = 2;

		from += more;
		sum++;
	}
	return sum;
}

size_t UnicodeToUtf8(char *to, wchar_t *from, size_t need, size_t *buffer_lens)
{
	unsigned short c;
	size_t len = 0;
	char *p = to;
	int count = 1;
	if(need == (unsigned int)-1)
		count = 0;
	while((c = *from++)!=0)
	{
		if(count && (need-- <= 0))
			break;
		if(c < 0x0080)
		{
			len ++;
			if(buffer_lens && (*buffer_lens < len))
			{
				len = (unsigned int)-1;
				break;
			}
			*p++ = c & 0x7f;
		}
		else if(!(c & 0xf800))
		{
			len += 2;
			if(buffer_lens && (*buffer_lens < len))
			{
				len = (unsigned int)-1;
				break;
			}
			*p++ = 0xc0 | (c >> 11);
			*p++ = 0x80 | (c & 0x3f);
		}
		else
		{
			len += 3;
			if(buffer_lens && (*buffer_lens < len))
			{
				len = (unsigned int)-1;
				break;
			}
			*p++ = 0xe0 | (c >> 12);
			*p++ = 0x80 | ((c >> 6) & 0x3f);
			*p++ = 0x80 | (c & 0x3f);
		}
	}
	if(buffer_lens && (*buffer_lens < len + 1))
		return (unsigned int)-1;
	*p = 0;
	return len;
}

size_t Utf8ToUnicode(wchar_t *to, char *from, size_t lens)
{
	size_t sum;
	unsigned short c;
	int more;
	int count = 1;
	if(lens == -1)
		count = 0;
	sum = 0;
	while(c = (unsigned short)(*from++))
	{
		if(count && (lens-- <= 0))
			break;

		c &= 0xff;
		if(c < 0x80)
		{
			more = 0;
		}
		else if(c < 0x00e0)
		{
			more = 1;
			c &= 0x1f;
		}
		else
		{
			more = 2;
			c &= 0x0f;
		}

		sum++;
		lens -= more;

		while(more--)
		{
			if((*from & 0xc0) != 0x80)
			{
				sum = -1;
				break;
			}

		    c = (c << 6) + ((*from++) & 0x3f);
		}
		*to++ = c;
	}
	*to = 0;
	return sum;
}

int char_to_bit7(char *dest, char *src, int size)
{
	char *s, *d;
	int n, ret;
	if(!dest || !src)
		return -1;
	s = src;
	d = dest;
	n = 0;
	ret = 0;
	while(size--)
	{
		if(size > 0)
		{
			*d++ = ((unsigned char)*s >> n) | (*(s + 1) << (7 - n));
			n++;
			if(n == 7)
			{
				size--;
				s++;
			}
		}
		else
			*d++ = *s >> n;
		s++;
		n %= 7;
		ret++;
	}
	return ret;
}

int bit7_to_char(char *dest, char *src, int size)
{
	char *s, *d;
	int n, ret, first;
	if(!dest || !src)
		return -1;
	s = src;
	d = dest;
	n = 0;
	ret = 0;
	first = 1;
	while(size--)
	{
		if(first)
		{
			first = 0;
			*d++ = *s & 0x7f;
		}
		else if(n != 7)
			*d++ = ((*s << n) | ((unsigned char)*(s - 1) >> (8 - n))) & 0x7f;
		else
			*d++ = ((unsigned char)*(s - 1) >> (8 - n)) & 0x7f;

		if(n == 7)
			n = 0;
		else
		{
			n++;
			s++;
		}
		ret++;
	}
	*d = 0;
	return ret;
}

